﻿namespace Services
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Entities;
    using DAL;

    public class DetailsService : IDetailsService
    {
        #region Member Variables
        protected readonly IGenericRepository<FAEntities, AuditedOperation> repository;
        #endregion

        #region Constructor
        public DetailsService(IGenericRepository<FAEntities, AuditedOperation> repository)
        {
            this.repository = repository;
        }
        #endregion

        #region IDetailsService

        IEnumerable<AuditedOperation> IDetailsService.GetFileActions(string fileName, FilterOperations filter)
        {
            var operations = from o in repository.Context.AuditedOperations
                             where o.ObjectName == fileName
                             select o;

            return Common.FilterOperations(filter, ref operations);
        }

        UserDetailsModel IDetailsService.GetUserActions(string userName, FilterOperations filter)
        {
            var userOperations = from o in repository.Context.AuditedOperations
                                 where o.UserAccount == userName
                                 select o;

            var filteredOperations = Common.FilterOperations(filter, ref userOperations);

            var userDetails = new UserDetailsModel();

            userDetails.CreatedCount = GetOeprationsCount(filteredOperations, OperationType.Create);
            userDetails.DeletedCount = GetOeprationsCount(filteredOperations, OperationType.Deleted);
            userDetails.MovedCount = GetOeprationsCount(filteredOperations, OperationType.Move);
            userDetails.RenamedCount = GetOeprationsCount(filteredOperations, OperationType.Rename);
            userDetails.TotalOperationsCount = filteredOperations.Count();
            userDetails.LastActivityDate = GetUsersLastActivityDate(filteredOperations);
            userDetails.UsedMachines = GetUsersMachines(filteredOperations);

            return userDetails;
        }

        #endregion

        #region Private Methods

        private int GetOeprationsCount(IEnumerable<AuditedOperation> filteredOperations, OperationType operationType)
        {

            return filteredOperations.Where(au => au.OperationType == (int)operationType).Count();
        }

        private Dictionary<string, int> GetUsersMachines(IEnumerable<AuditedOperation> filteredOperations)
        {
            var usersMachines = from operation in filteredOperations
                                group operation by operation.ClientMachineName into g
                                select new { MachineName = g.Key, OperationsCount = g.Count() };
            return usersMachines.ToDictionary(o => o.MachineName, o => o.OperationsCount);
        }

        private DateTime GetUsersLastActivityDate(IEnumerable<AuditedOperation> filteredOperations)
        {
            var lastDate = from o in filteredOperations
                           orderby o.ReceivedTime descending
                           select o.ReceivedTime;
            return lastDate.First().Value;
        }

        #endregion
    }
}